import { blobOrFileToArray } from './object'
async function objToJSOnObj(obj) {
    if (obj instanceof Blob || obj instanceof File) {
        let arr = await blobOrFileToArray(obj)
        return arr
    } else if (typeof obj === 'object') {
        let cp = Object.assign({}, obj)
        for (let k in cp) {
            cp[k] = await objToJSOnObj(obj[k])
        }
        return cp
    } else {
        return obj
    }
}
async function serialize(obj) {
    return JSON.stringify(await objToJSOnObj(obj))
}
function deserialize(obj) {
    let data
    if (typeof obj === 'string') {
        data = JSON.parse(obj)
    }
    return data
}

export default class SocketPeer {
    constructor(peerId, obj) {
        this.host = obj.host || '127.0.0.1'
        this.port = obj.port || 45631
        this.protocol = obj.secure === true ? "wss" : obj.secure === false ? "ws" : "wss"
        this.path = obj.path || '/'
        if (!this.path.endsWith('/')) {
            this.path = this.path + '/'
        }
        this.key = obj.key || ''
        this.peerId = peerId
        this.eventMap = {}
        this.connMap = {}
        this.connectServer()
    }
    on(event, callback) {
        let ls = this.eventMap[event]
        if (!ls) {
            ls = []
            this.eventMap[event] = ls
        }
        ls.push(callback)
    }
    reconnect() {

    }
    connect(otherPeerId) {
        if (this.connMap[otherPeerId]) {
            return this.connMap[otherPeerId]
        }
        console.log("otherPeerId", otherPeerId)
        //返回一个SocketPeerConn对象
        this.ws.send(JSON.stringify({
            event: 'connect',
            otherPeerId: otherPeerId,
            senderPeerId: this.peerId
        }))
        let conn = new SocketPeerConn(otherPeerId, this.ws)
        this.connMap[otherPeerId] = conn
        return conn
    }

    connectServer() {
        let query = []
        query.push("peerId=" + this.peerId)
        query.push("abc=def")
        this.ws = new WebSocket(this.protocol + "://" + this.host + ":" + this.port + this.path + this.key + "?" + query.join("&"));
        this.ws.addEventListener('message', (event) => {
            let message = deserialize(event.data)
            console.log("接收到消息：", message);
            //与服务器连接打开的消息
            if (message.event === 'open') {
                if (message.peerId == this.peerId) {
                    this.callEvent('open', message.peerId)
                }
            } else if (message.event === 'error') {
                //出现错误的消息
                this.callEvent('error', message.data)
            } else if (message.event === 'friend_close') {
                //伙伴掉线通知
                console.log(message)
                console.log(this.connMap)
                this.connMap[message.otherPeerId].callEvent("close", message.otherPeerId)
            } else if (message.event === 'connect' && !this.connMap[message.otherPeerId]) {
                console.log("connection...", message.otherPeerId)
                let conn = new SocketPeerConn(message.otherPeerId, this.ws)
                this.connMap[message.otherPeerId] = conn
                //被连接的消息
                if (message.yourPeerId === this.peerId) {
                    //告诉自己被连接，并且连接已打开
                    this.callEvent('connection', conn)
                    conn.callEvent("open", message.otherPeerId)
                } else {
                    console.debug("不应该错误", message)
                }
            } else {
                this.callEvent('data', message)
            }
        });

        // 连接关闭时的回调函数
        this.ws.addEventListener('close', (event) => {
            this.callEvent('disconnection', event)
            console.log("Socket连接已关闭");
        });

        // 发生错误时的回调函数
        this.ws.addEventListener('error', (error) => {
            this.callEvent('error', error)
            console.error("Socket连接发生错误:", error);
        });
    }

    call() {

    }

    callEvent(event, data) {
        let ls = this.eventMap[event]
        if (!ls) {
            ls = []
            this.eventMap[event] = ls
        }
        if (ls.length == 0) {
            console.debug("事件监听器为0")
        }
        ls.forEach(cb => {
            cb(data)
        });
        return this
    }
}
class SocketPeerConn {
    constructor(peerId, ws) {
        this.peerId = peerId
        this.connectionId = peerId
        this.eventMap = {}
        this.ws = ws
        this.initEvent()
        this.open = true
    }
    async send(obj) {
        let data = await serialize(obj)
        this.ws.send(data)
    }
    initEvent() {
        this.ws.addEventListener('message', event => {
            let message = deserialize(event.data)
            if (message.event === 'connect') {
                this.callEvent('open')
            } else if (message.event === 'friend_close') {
                this.callEvent('close')
            } else {
                this.callEvent("data", message)
            }
        })
    }
    on(event, callback) {
        let ls = this.eventMap[event]
        if (!ls) {
            ls = []
            this.eventMap[event] = ls
        }
        ls.push(callback)
    }

    callEvent(event, data) {
        let ls = this.eventMap[event]
        if (!ls) {
            ls = []
            this.eventMap[event] = ls
        }
        if (ls.length == 0) {
            console.log("事件监听器=", ls.length)
        }
        ls.forEach(cb => {
            cb(data)
        });
        return this
    }
}